﻿using System;
using System.Collections.Generic;
using System.Text;

namespace UVMComm
{
    // 데이터 타입이 추가되면 Enumeration에 추가합니다!
    #region Datatype Enumeration
    public enum DATATYPE { CLA01DATA, CLA02DATA };
    #endregion

    class Packet
    {
        #region DataMember
        private PacketHeader m_header;
        private IData m_data;
        private bool m_isReply;
        #endregion

        #region Properties
        public IData DATA
        {
            get { return m_data; }
            set { m_data = value; }
        }
        public PacketHeader HEADER
        {
            get { return m_header; }
            set { m_header = value; }
        }
        public int Length
        {
            get { return 4 + m_data.Length; }
        }
        public bool IsReply
        {
            get { return m_isReply; }
            set { m_isReply = value; }
        }
        #endregion

        #region Constructors
        public Packet(byte cla, byte ins, IData data)
        {
            DATA = data;
            HEADER = GetHeaderInstance(cla, ins, DATA.Length);
            IsReply = false;
        }
        public Packet(byte[] packet)
        {
            List<byte> packetList = new List<byte>();
            packetList.AddRange(packet);
            byte[] headerbytes = new byte[4];
            byte[] databytes = new byte[packet.Length - 4];

            // Make Header
            for (int i = 0; i < headerbytes.Length; i++)
                headerbytes[i] = packetList[i];

            packetList.RemoveRange(0, 4);

            // Make Data
            for (int i = 0; i < packetList.Count; i++)
                databytes[i] = packetList[i];

            HEADER = new PacketHeader(headerbytes);
            DATA = new IData(databytes);
            IsReply = true;
        }
        #endregion

        #region public Mehtods
        public byte[] GetBytes()
        {
            List<byte> retList = new List<byte>();
            retList.AddRange(HEADER.GetBytes());
            retList.AddRange(DATA.GetBytes());
            return retList.ToArray();
        }
        public byte GetResponse()
        {
            if (m_isReply == true)
                return DATA.DATA[0];
            else
                throw new Exception("This is Not Response Packet!!");
        }
        #endregion

        #region GetInstance Methods
        static private PacketHeader GetHeaderInstance(byte cla, byte ins, int datasize)
        {
            return new PacketHeader(cla, ins, datasize);
        }
        // 데이터 타입이 추가되면 GetDataInstance를 수정합니다.
        static public IData GetDataInstance(DATATYPE tp, params object[] args)
        {
            switch (tp)
            {
                case DATATYPE.CLA01DATA:
                    return new CLA01DATA(args);
                case DATATYPE.CLA02DATA:
                    return new CLA02DATA(args);
            }
            return null;
        }
        #endregion
    }
}